
// Http请求辅助类 
class FetchApi {

    /**
     * 获取用户会话信息。会话信息应该在登录成功后记录到本地，并通过此方法能获取到。
     * @returns 代表用户会话的对象 
     */
    static getAuthToken() {
        let j = window.sessionStorage.getItem('Userinfo');
        if (j) {
            return JSON.parse(j).AuthorizedCode;
        }
        return null;
    }

    /**
     * 执行一个Http Get请求，返回一个Promise
     * @param path 接口路径,比如获取机构列表的地址：/api/account/getorgs
     * @param params 请求参数，Object格式，会被序列化后转为url参数格式
     * @param callback 回调函数
     * @param noAuth 此请求是否无需登录，比如获取机构列表、登录等请求。 
     */
    static async get(path, params, callback, noAuth = false) {
        if (!this.host) {
            let msg = '请配置服务器地址';
            Toast.error(msg);
            callback && callback(null);
            return new Promise((resolve, reject) => {
                resolve(msg);
            });
        }
        if (!noAuth && !FetchApi.getAuthToken()) {
            let msg = '会话超时或尚未登录';
            Toast.error(msg);
            callback && callback(null);
            return new Promise((resolve, reject) => {
                resolve(msg);
            });
        }

        var url = this.host + path;
        if (params) {
            let paramsArray = [];
            Object.keys(params).forEach((key) =>
                paramsArray.push(key + '=' + encodeURIComponent(params[key])),
            );
            if (url.search(/\?/) === -1) {
                url += '?' + paramsArray.join('&');
            } else {
                url += '&' + paramsArray.join('&');
            }
        }

        let header = {
            'Content-Type': 'application/json',
        };
        if (!noAuth) {
            header['Authorization'] = 'BasicAuth ' + FetchApi.getAuthToken();
        }

        return new Promise(function (resolve, reject) {
            fetch(url, {
                method: 'GET',
                headers: header,
            })
                .then((response) => {
                    let handleExp = handleException(response, url, true);
                    if (handleExp.then) {
                        handleExp.then((r) => {
                            if (r === 'done') {
                                var _p = FetchApi.get(path, params, callback, noAuth);
                                _p.then((result) => {
                                    resolve(result);
                                });
                            }
                        });
                        return;
                    } else if (handleExp === false) {
                        callback && callback(null);
                        resolve(null);
                        return;
                    }

                    response
                        .json()
                        .then((result) => {
                            callback && callback(result);
                            resolve(result);
                        })
                        .catch((error) => {
                            Toast.error(error.toString());
                            callback && callback(null);
                            resolve(null);
                        });
                })
                .catch(function (error) {
                    handleNetworkError(error);
                    callback && callback(null);
                    resolve(null);
                });
        });
    }

    /**
     * 执行一个Http Post请求，返回一个Promise
     * @param path 接口路径 
     * @param bodyObj 发送的内容
     * @param callback 回调函数
     * @param noAuth 此请求是否无需登录，比如获取机构列表、登录等请求 
     */
    static async post(path, bodyObj, callback, noAuth = false) {
        if (!this.host) {
            let msg = '请配置服务器地址';
            Toast.error(msg);
            callback && callback(null);
            return new Promise((resolve, reject) => {
                resolve(msg);
            });
        }
        if (!noAuth && !FetchApi.getAuthToken()) {
            let msg = '会话超时或尚未登录';
            Toast.error(msg);
            callback && callback(null);
            return new Promise((resolve, reject) => {
                resolve(msg);
            });
        }

        var url = this.host + path;
        if (bodyObj) {
        }

        let header = {
            'Content-Type': 'application/json',
        };
        if (!noAuth) {
            header['Authorization'] = 'BasicAuth ' + FetchApi.getAuthToken();
        }

        return new Promise(function (resolve, reject) {
            fetch(url, {
                method: 'POST',
                headers: header,
                body: JSON.stringify(bodyObj || {}),
            })
                .then((response) => {
                    let handleExp = handleException(response, url, true);
                    if (handleExp.then) {
                        handleExp.then((r) => {
                            if (r === 'done') {
                                var _p = FetchApi.post(path, bodyObj, callback, noAuth);
                                _p.then((result) => {
                                    resolve(result);
                                });
                            }
                        });
                        return;
                    } else if (handleExp === false) {
                        callback && callback(null);
                        resolve(null);
                        return;
                    }

                    response
                        .json()
                        .then((result) => {
                            callback && callback(result);
                            resolve(result);
                        })
                        .catch((error) => {
                            Toast.error(error.toString());
                            callback && callback(null);
                            resolve(null);
                        });
                })
                .catch(function (error) {
                    handleNetworkError(error);
                    callback && callback(null);
                    resolve(null);
                });
        });
    }


    // 获取机构列表 
    static async getOrg(callback) {
        return FetchApi.get(
            '/api/account/getorgs',
            null,
            function (jsonResult) {
                callback && callback(jsonResult);
            },
            true,
        );
    }
    // 登录（使用用户名和密码） 
    static async login(data, callback) {
        return await FetchApi.get(
            '/api/account/Login',
            data,
            function (jsonResult) {
                if (jsonResult) {
                    var loginResult = jsonResult;
                    if (loginResult.State !== '1') {
                        Toast.error(loginResult.Msg);
                    } else {
                        // 登录成功后将记录用户信息 
                        window.sessionStorage.setItem(
                            'Userinfo',
                            JSON.stringify(loginResult.Data),
                        );
                    }

                    callback && callback(loginResult);
                }
            },
            true,
        );
    }
    // 登出
    static async logout(callback) {
        if (!FetchApi.getAuthToken() && callback) {
            callback();
            return new Promise((resolve, reject) => {
                resolve('ok');
            });
        } else {
            return this.get('/api/account/Logout', null, function (jsonResult) {
                window.sessionStorage.removeItem('Userinfo');
                callback && callback();
            });
        }
    }
}
// 此处需要配置ERP的主机地址 
FetchApi.host = '';//window.location.origin;
FetchApi.isRefreshingToken = 0;

function handleException(response, url, redo) {
    if (response.ok) {
        return true;
    }

    // response.text().then((result) => {
    //     console.log('response.status:' + response.status + '. ' + result);
    // });

    if (response.status === 410 && response.headers.get('app-permission-denied')) {
        Toast.error('您的操作未授权，请授权限后再操作');
        return false;
    }

    if (response.status === 401) {
        console.log('未登录或会话超时');

        if (response.headers.get('session-timeout')) {
            // 这里处理会话超时：
            // 刷新token后重新发起当前请求 
            if (redo) {
                console.log('正在刷新登录并重试当前操作');
                return new Promise((resolve, reject) => {
                    if (FetchApi.isRefreshingToken === 'pending') {
                        var interval = setInterval(function () {
                            if (FetchApi.isRefreshingToken !== 'pending') {
                                clearInterval(interval);
                                if (FetchApi.isRefreshingToken === 'done') {
                                    resolve('done');
                                } else {
                                    resolve('fail');
                                }
                            }
                        }, 1500);
                    } else {
                        FetchApi.isRefreshingToken = 'pending';
                        FetchApi.get(
                            '/api/account/RefreshToken',
                            { authCode: FetchApi.getAuthToken() },
                            function (jsonResult) {
                                if (jsonResult) {
                                    var loginResult = jsonResult;
                                    if (loginResult.State === '1') {
                                        resolve('done');
                                        FetchApi.isRefreshingToken = 'done';
                                    } else {
                                        Toast.error(loginResult.Msg);
                                        resolve('fail');
                                        FetchApi.isRefreshingToken = 'fail';
                                    }
                                } else {
                                    resolve('fail');
                                    FetchApi.isRefreshingToken = 'fail';
                                }
                            },
                        );
                    }
                });
            }
        }

        return false;
    }
    // Not Found 请求的资源不存在
    if (response.status === 404) {
        Toast.error('请求的资源不存在，请确认');
        return false;
    }
    // Internal Server Error  服务器返回一个错误
    else if (response.status === 500) {
        Toast.error('服务器响应错误，请重试或联系管理员');
        return false;
    }
    // Service Unavailable 服务器不可用
    else if (response.status === 503) {
        Toast.error('服务不可用，请稍后重试');
        return false;
    } else {
        // 其他错误
        Toast.error(`服务异常，状态码：${response.status}`);
        return false;
    }
}
function handleNetworkError(error) {
    Toast.error('网络请求失败，无法连接到服务器');
    console.log('fetch error:' + error);
}

// 消息提示 
const Toast = {
    error: (content) => {
        alert(content);
    },
};

export default FetchApi;